package cn.ug.analyse.service.impl;

import cn.ug.analyse.bean.request.WithdeawParamBean;
import cn.ug.analyse.bean.response.BaseCountBean;
import cn.ug.analyse.mapper.MemberHoldGoldMapper;
import cn.ug.analyse.mapper.entity.MemberBalance;
import cn.ug.analyse.mapper.entity.MemberHold;
import cn.ug.analyse.service.MemberHoldGoldService;
import cn.ug.bean.base.DataTable;
import cn.ug.bean.base.Page;
import cn.ug.core.ensure.Ensure;
import cn.ug.pay.bean.request.AccountFinanceBillParam;
import cn.ug.pay.bean.response.MemberAccountBean;
import cn.ug.util.BigDecimalUtil;
import cn.ug.util.Common;
import cn.ug.util.UF;
import cn.ug.util.Week;
import com.github.pagehelper.PageHelper;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class MemberHoldGoldServiceImpl implements MemberHoldGoldService {

    @Resource
    private MemberHoldGoldMapper memberHoldGoldMapper;

    private static Logger logger = LoggerFactory.getLogger(MemberHoldGoldServiceImpl.class);


    @Override
    public DataTable<BaseCountBean> findList(WithdeawParamBean withdeawParamBean) {
        List<BaseCountBean> resultList = new ArrayList<BaseCountBean>();

        if(StringUtils.isBlank(withdeawParamBean.getStartTime())) withdeawParamBean.setStartTime(LocalDate.now().plusDays(-7).toString());
        if(StringUtils.isBlank(withdeawParamBean.getEndTime())) withdeawParamBean.setEndTime(LocalDate.now().plusDays(-1).toString());

        //参数必须传递--起始时间、结束时间
        Ensure.that(withdeawParamBean.getStartTime()).isNull("21000001");
        Ensure.that(withdeawParamBean.getEndTime()).isNull("21000002");
        Ensure.that(withdeawParamBean.getPageType()).isNull("21000004");

        int pageNum = withdeawParamBean.getPageNum();
        int pageSize = withdeawParamBean.getPageSize();
        withdeawParamBean.setPageNum(1);
        withdeawParamBean.setPageSize(100000);
        List<BaseCountBean> list = memberHoldGoldMapper.findList(withdeawParamBean);
        resultList = findEverydayList(withdeawParamBean);  //每日


        //数据分页
        if(resultList != null && !resultList.isEmpty()) {
            Collections.reverse(resultList);  //倒序排列

            //查询是否分页
            if(withdeawParamBean.getPageType() == 2){
                int total = resultList.size();
                //计算
                int num = (pageNum-1)* pageSize;
                resultList = resultList.stream().skip(num).collect(Collectors.toList());
                List<BaseCountBean> pageList = resultList.stream().limit(pageSize).collect(Collectors.toList());
                return new DataTable<>(pageNum, pageSize, total, pageList);
            }else{
                return new DataTable<>(pageNum, pageSize, resultList.size(), resultList);
            }
        }else {
            return new DataTable<>(pageNum, withdeawParamBean.getPageSize(), 0, new ArrayList<>());
        }
    }

    @Override
    public BigDecimal findTotal(WithdeawParamBean withdeawParamBean) {
        List<BaseCountBean> resultList = new ArrayList<BaseCountBean>();

        //参数必须传递--起始时间、结束时间
        Ensure.that(withdeawParamBean.getStartTime()).isNull("21000001");
        Ensure.that(withdeawParamBean.getEndTime()).isNull("21000002");

        //List<BaseCountBean> list = memberHoldGoldMapper.findList(withdeawParamBean);
        withdeawParamBean.setPageNum(1);
        withdeawParamBean.setPageSize(100000);
        resultList = findEverydayList(withdeawParamBean);  //每日
        BigDecimal amount = BigDecimal.ZERO;
        for(BaseCountBean entity: resultList){
            amount = amount.add(entity.getAmount());
        }
        return amount;
    }

    @Override
    public DataTable<BaseCountBean> findNewGoldList(WithdeawParamBean withdeawParamBean) {
        List<BaseCountBean> resultList = new ArrayList<BaseCountBean>();

        if(StringUtils.isBlank(withdeawParamBean.getStartTime())) withdeawParamBean.setStartTime(LocalDate.now().plusDays(-7).toString());
        if(StringUtils.isBlank(withdeawParamBean.getEndTime())) withdeawParamBean.setEndTime(LocalDate.now().plusDays(-1).toString());

        //参数必须传递--起始时间、结束时间
        Ensure.that(withdeawParamBean.getStartTime()).isNull("21000001");
        Ensure.that(withdeawParamBean.getEndTime()).isNull("21000002");
        Ensure.that(withdeawParamBean.getDayType()).isNull("21000003");
        Ensure.that(withdeawParamBean.getPageType()).isNull("21000004");

        int pageNum = withdeawParamBean.getPageNum();
        int pageSize = withdeawParamBean.getPageSize();
        withdeawParamBean.setPageNum(1);
        withdeawParamBean.setPageSize(100000);
        //每日统计
        resultList = findEverydayList(withdeawParamBean);
        //resultList = disposeNewGoldList(resultList);

        //算出每日新增克重
        switch (withdeawParamBean.getDayType()){
            case 2: resultList = findEvenyWeek(withdeawParamBean, resultList); break;   //获取每周数据
            case 3: resultList = findEveryMonth(withdeawParamBean, resultList);break;   //获取每月数据
        }
        //数据处理
        if(withdeawParamBean.getDayType() == 1){
            resultList = disposeNewGoldList(resultList);
        }

        //数据分页
        if(resultList != null && !resultList.isEmpty()) {
            Collections.reverse(resultList);  //倒序排列

            //查询是否分页
            if(withdeawParamBean.getPageType() == 2){
                int total = resultList.size();
                //计算
                int num = (pageNum-1)* pageSize;
                resultList = resultList.stream().skip(num).collect(Collectors.toList());
                List<BaseCountBean> pageList = resultList.stream().limit(pageSize).collect(Collectors.toList());
                return new DataTable<>(pageNum, pageSize, total, pageList);
            }else{
                return new DataTable<>(pageNum, pageSize, resultList.size(), resultList);
            }
        }else {
            return new DataTable<>(pageNum, pageSize, 0, new ArrayList<>());
        }
    }

    @Override
    public BigDecimal findNewGoldTotal(WithdeawParamBean withdeawParamBean) {
        List<BaseCountBean> resultList = new ArrayList<BaseCountBean>();

        if(StringUtils.isBlank(withdeawParamBean.getStartTime())) withdeawParamBean.setStartTime(LocalDate.now().plusDays(-7).toString());
        if(StringUtils.isBlank(withdeawParamBean.getEndTime())) withdeawParamBean.setEndTime(LocalDate.now().plusDays(-1).toString());

        //参数必须传递--起始时间、结束时间
        Ensure.that(withdeawParamBean.getStartTime()).isNull("21000001");
        Ensure.that(withdeawParamBean.getEndTime()).isNull("21000002");
        Ensure.that(withdeawParamBean.getDayType()).isNull("21000003");

        //每日统计
        withdeawParamBean.setPageNum(1);
        withdeawParamBean.setPageSize(100000);
        resultList = findEverydayList(withdeawParamBean);
        //resultList = disposeNewGoldList(resultList);

        //算出每日新增克重
        switch (withdeawParamBean.getDayType()){
            case 2: resultList = findEvenyWeek(withdeawParamBean, resultList); break;   //获取每周数据
            case 3: resultList = findEveryMonth(withdeawParamBean, resultList);break;   //获取每月数据
        }
        //数据处理
        if(withdeawParamBean.getDayType() == 1){
            resultList = disposeNewGoldList(resultList);
        }
        BigDecimal amount = BigDecimal.ZERO;
        for(BaseCountBean entity: resultList){
            amount = amount.add(entity.getAmount());
        }
        return amount;
    }

    @Override
    public void memberHoldJob() {
        LocalDate currentDate = LocalDate.now();
        currentDate = currentDate.plusDays(-1);
        memberHoldCount(currentDate.toString());
    }

    /**
     * 计算持有量
     * @param startTime
     */
    public void memberHoldCount(String startTime){
        /*//获取定期冻结部分克重
        BigDecimal freezeAmount = memberHoldGoldMapper.findFreezeAmount(startTime);
        //定期已到期克重(本金+利息)
        BigDecimal expiredAmount = memberHoldGoldMapper.findExpiredAmount(startTime);
        //活期利息
        BigDecimal currentInterestAmount = memberHoldGoldMapper.findCurrentInterest(startTime);
        //查询人民币购买活期产品
        BigDecimal moneyCurrentAmount = memberHoldGoldMapper.findMoneyCurrent(startTime);
        //提金克重和卖金克重
        BigDecimal payAmount = memberHoldGoldMapper.findPayAmount(startTime);

        //计算总克重
        BigDecimal holdAmount = freezeAmount.add(expiredAmount).add(currentInterestAmount).add(moneyCurrentAmount).subtract(payAmount);
*/
        BigDecimal holdAmount = new BigDecimal(memberHoldGoldMapper.getHoldGold());
        MemberHold memberHold = new MemberHold();
        memberHold.setId(UF.getRandomUUID());
        memberHold.setDay(startTime.toString());
        memberHold.setAmount(holdAmount);
        memberHoldGoldMapper.insert(memberHold);
    }
    public void memberHoldGoldScript(String startTimeString,String endTimeString){
        LocalDate startTime = LocalDate.parse(startTimeString, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        LocalDate endTime = LocalDate.parse(endTimeString, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        while (startTime.compareTo(endTime) <= 0){
            memberHoldCount(startTime.toString());
            startTime = startTime.plusDays(1);
        }
    }

    public List<BaseCountBean> findEverydayList(WithdeawParamBean withdeawParamBean) {
        List<BaseCountBean> resultList = new ArrayList<BaseCountBean>();
        List<BaseCountBean> list = memberHoldGoldMapper.findList(withdeawParamBean);

        //设置开始时间
        LocalDate startTime = LocalDate.parse(withdeawParamBean.getStartTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        LocalDate endTime = LocalDate.parse(withdeawParamBean.getEndTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        //获取查询出的天数
        int day = Integer.valueOf(Common.until(startTime,endTime) +"") + 1;
        for(int i = 0;i< day;i++) {
            //当前日期时间字符串
            String startTimeString = startTime.toString();
            BaseCountBean entity = new BaseCountBean();
            entity.setDay(startTimeString);
            entity.setDayNumber(Integer.valueOf(startTime.format(DateTimeFormatter.ofPattern("yyyyMMdd"))));
            if(list != null && !list.isEmpty()){
                List<BaseCountBean> filterList = list.stream().filter(o -> o.getDay().contains(startTimeString)).collect(Collectors.toList());
                if(filterList != null && !filterList.isEmpty()){
                    entity.setAmount(filterList.get(0).getAmount());
                }else{
                    entity.setAmount(BigDecimalUtil.to2Point(BigDecimal.ZERO));
                }
            }else{
                entity.setAmount(BigDecimalUtil.to2Point(BigDecimal.ZERO));
            }
            resultList.add(entity);
            startTime = startTime.plusDays(1);
        }
        return resultList;
    }
    /**
     * 按周统计
     * @param withdeawParamBean
     * @return
     */
    public List<BaseCountBean> findEvenyWeek(WithdeawParamBean withdeawParamBean, List<BaseCountBean> list){
        List<BaseCountBean> resultList = new ArrayList<BaseCountBean>();

        //根据起始时间和结束时间获取周
        LocalDate startTime = LocalDate.parse(withdeawParamBean.getStartTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        LocalDate endTime = LocalDate.parse(withdeawParamBean.getEndTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        List<Week> weekList = Common.getWeekList(startTime, endTime);


        for(Week week:weekList){
            BaseCountBean baseCountBean = new BaseCountBean();
            baseCountBean.setDay(week.getDay());
            BigDecimal amount = BigDecimal.ZERO;

            if(list != null && !list.isEmpty()){
                List<BaseCountBean> startList = list.stream().filter(o -> o.getDayNumber().equals(week.getStartTimeNumber())).collect(Collectors.toList());
                List<BaseCountBean> endList = list.stream().filter(o -> o.getDayNumber().equals(week.getEndTimeNumber())).collect(Collectors.toList());
                if(startList != null && !startList.isEmpty() &&  endList != null && !endList.isEmpty()){
                    amount = endList.get(0).getAmount().subtract(startList.get(0).getAmount());
                }
            }
            baseCountBean.setAmount(amount);
            resultList.add(baseCountBean);
        }

        //统计
        resultList = disposeNewGoldList(resultList);
        return resultList;
    }

    /**
     * 按月统计
     * @param withdeawParamBean
     * @return
     */
    public List<BaseCountBean> findEveryMonth(WithdeawParamBean withdeawParamBean, List<BaseCountBean> list){
        List<BaseCountBean> resultList = new ArrayList<BaseCountBean>();
        List<String> monthList = new ArrayList<String>();

        //参数必须传递--起始时间、结束时间
        Ensure.that(withdeawParamBean.getStartTime()).isNull("21000001");
        Ensure.that(withdeawParamBean.getEndTime()).isNull("21000002");

        //设置开始时间
        LocalDate startTime = LocalDate.parse(withdeawParamBean.getStartTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        LocalDate endTime = LocalDate.parse(withdeawParamBean.getEndTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM");
        String endMonth = df.format(endTime);
        while(true){
            String month  = df.format(startTime);
            monthList.add(month);
            if(month.equals(endMonth)){
                break;
            }else{
                startTime = startTime.plusMonths(1);
            }
        }

        //数据遍历
        if(monthList != null && !monthList.isEmpty()){
            for(int i=0;i<monthList.size();i++){
                BaseCountBean baseCountBean = new BaseCountBean();
                baseCountBean.setDay(monthList.get(i));
                Integer num = i;
                if(list != null && !list.isEmpty()){
                    LocalDate firstDay = LocalDate.parse(monthList.get(num).toString()+"-01", DateTimeFormatter.ofPattern("yyyy-MM-dd")).with(TemporalAdjusters.firstDayOfMonth());
                    LocalDate lastDay = LocalDate.parse(monthList.get(num).toString()+"-01", DateTimeFormatter.ofPattern("yyyy-MM-dd")).with(TemporalAdjusters.lastDayOfMonth());

                    if(lastDay.compareTo(endTime) > 0) lastDay = endTime;

                    String firstDayString = firstDay.toString();
                    String lastDayString = lastDay.toString();

                    List<BaseCountBean> firstList = list.stream().filter(o -> o.getDay().equals(firstDayString)).collect(Collectors.toList());
                    List<BaseCountBean> lastList = list.stream().filter(o -> o.getDay().equals(lastDayString)).collect(Collectors.toList());
                    if(firstList != null && !firstList.isEmpty() &&  lastList != null &&  !lastList.isEmpty()){
                        if(!firstDayString.equals(lastDayString)){
                            //baseCountBean.setAmount(lastList.get(0).getAmount().subtract(firstList.get(0).getAmount()));
                            LocalDate lastMonth = firstDay.plusMonths(-1);
                            LocalDate lastMonthStartDay = LocalDate.parse(lastMonth.toString(), DateTimeFormatter.ofPattern("yyyy-MM-dd")).with(TemporalAdjusters.firstDayOfMonth());
                            LocalDate lastMonthEndDay = LocalDate.parse(lastMonth.toString(), DateTimeFormatter.ofPattern("yyyy-MM-dd")).with(TemporalAdjusters.lastDayOfMonth());
                            BigDecimal lastMonthStartAmount = memberHoldGoldMapper.findByDay(lastMonthStartDay.toString());
                            BigDecimal lastMonthEndAmount = memberHoldGoldMapper.findByDay(lastMonthEndDay.toString());
                            BigDecimal amount = lastMonthEndAmount.subtract(lastMonthStartAmount);
                            baseCountBean.setAmount(lastList.get(0).getAmount().subtract(amount));
                            //本月减去上个月
                        }else{
                            //baseCountBean.setAmount(lastList.get(0).getAmount());
                            LocalDate lastMonth = firstDay.plusMonths(-1);
                            LocalDate lastMonthStartDay = LocalDate.parse(lastMonth.toString(), DateTimeFormatter.ofPattern("yyyy-MM-dd")).with(TemporalAdjusters.firstDayOfMonth());
                            LocalDate lastMonthEndDay = LocalDate.parse(lastMonth.toString(), DateTimeFormatter.ofPattern("yyyy-MM-dd")).with(TemporalAdjusters.lastDayOfMonth());
                            BigDecimal lastMonthStartAmount = memberHoldGoldMapper.findByDay(lastMonthStartDay.toString());
                            BigDecimal lastMonthEndAmount = memberHoldGoldMapper.findByDay(lastMonthEndDay.toString());
                            BigDecimal amount = lastMonthEndAmount.subtract(lastMonthStartAmount);
                            baseCountBean.setAmount(firstList.get(0).getAmount().subtract(amount));
                            //本月减去上个月
                        }
                    }else if(firstList == null &&  lastList != null && !lastList.isEmpty()){
                        baseCountBean.setAmount(lastList.get(0).getAmount());
                    }else{
                        baseCountBean.setAmount(BigDecimal.ZERO);
                    }
                }else{
                    baseCountBean.setAmount(BigDecimal.ZERO);
                }
                resultList.add(baseCountBean);
            }
        }
        return resultList;
    }

    /**
     * 处理新增克重
     * @return
     */
    List<BaseCountBean> disposeNewGoldList(List<BaseCountBean> paramList){
        List<BaseCountBean> resultList = new ArrayList<BaseCountBean>();
        //计算出新增克重
        BigDecimal amount = BigDecimal.ZERO;
        for(BaseCountBean entity: paramList){
            BigDecimal total = entity.getAmount();
            entity.setAmount(entity.getAmount().subtract(amount));
            amount = total;
        }
        return  paramList;
    }


    public static void main(String[] args) {
        /*LocalDate startTime = LocalDate.parse("2018-06-30", DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        LocalDate endTime = LocalDate.parse("2018-06-30", DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        System.out.println(startTime.compareTo(endTime));*/
       /* BigDecimal amount = new BigDecimal("0");
        amount = amount.add(BigDecimal.valueOf(2l));
        amount = amount.add(BigDecimal.ZERO);
        System.out.println(amount);*/
    }
}
